package cn.iocoder.yudao.module.pay.bill.dal.mysql;

import cn.iocoder.yudao.framework.business.basic.dao.mapper.CoreMapper;
import cn.iocoder.yudao.framework.business.basic.dao.query.CoreLambdaQueryWrapper;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.api.pay.bill.enums.BillModeEnum;
import cn.iocoder.yudao.module.pay.bill.dal.dataobject.PayBillDO;
import cn.iocoder.yudao.module.pay.bill.vo.AppPayBillPageReqVO;
import cn.iocoder.yudao.module.pay.bill.vo.PayBillPageReqVO;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * 账单 Mapper
 *
 * @author yshop
 * @author 山野羡民
 */
@Mapper
public interface PayBillMapper extends CoreMapper<PayBillDO> {

    default PageResult<PayBillDO> selectPage(PayBillPageReqVO reqVO) {
        return selectPage(reqVO, buildQueryWrapper(reqVO));
    }

    private CoreLambdaQueryWrapper<PayBillDO> buildQueryWrapper(PayBillPageReqVO reqVO) {
        return new CoreLambdaQueryWrapper<PayBillDO>()
                .eqIfPresent(PayBillDO::getRelateId, reqVO.getRelateId())
                .eqIfPresent(PayBillDO::getUserId, reqVO.getUserId())
                .eqIfPresent(PayBillDO::getMode, reqVO.getMode())
                .eqIfPresent(PayBillDO::getCategory, reqVO.getCategory())
                .eqIfPresent(PayBillDO::getType, reqVO.getType())
                .betweenIfPresent(PayBillDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(PayBillDO::getId);
    }

    default Double selectNumberSum(Long userId, AppPayBillPageReqVO reqVO) {
        CoreLambdaQueryWrapper<PayBillDO> wrapper = new CoreLambdaQueryWrapper<>();
        wrapper.select(PayBillDO::getNumber);
        wrapper.eqIfPresent(PayBillDO::getUserId, userId);
        wrapper.eqIfPresent(PayBillDO::getMode, reqVO.getMode());
        wrapper.eqIfPresent(PayBillDO::getCategory, reqVO.getCategory());
        wrapper.eqIfPresent(PayBillDO::getType, reqVO.getType());
        wrapper.betweenIfPresent(PayBillDO::getCreateTime, reqVO.buildCreateTime());
        List<Double> objs = selectObjs(wrapper, PayBillDO::getNumber);
        return objs.stream().reduce(0d, Double::sum);
    }

    default Double selectInNumberSum(Long userId, AppPayBillPageReqVO reqVO) {
        CoreLambdaQueryWrapper<PayBillDO> wrapper = new CoreLambdaQueryWrapper<>();
        wrapper.select(PayBillDO::getNumber);
        wrapper.eqIfPresent(PayBillDO::getUserId, userId);
        wrapper.eq(PayBillDO::getMode, BillModeEnum.INCOME.getValue());
        wrapper.eqIfPresent(PayBillDO::getCategory, reqVO.getCategory());
        wrapper.eqIfPresent(PayBillDO::getType, reqVO.getType());
        wrapper.betweenIfPresent(PayBillDO::getCreateTime, reqVO.buildCreateTime());
        List<Double> objs = selectObjs(wrapper, PayBillDO::getNumber);
        return objs.stream().reduce(0d, Double::sum);
    }

    default Double selectOutNumberSum(Long userId, AppPayBillPageReqVO reqVO) {
        CoreLambdaQueryWrapper<PayBillDO> wrapper = new CoreLambdaQueryWrapper<>();
        wrapper.select(PayBillDO::getNumber);
        wrapper.eqIfPresent(PayBillDO::getUserId, userId);
        wrapper.eq(PayBillDO::getMode, BillModeEnum.EXPEND.getValue());
        wrapper.eqIfPresent(PayBillDO::getCategory, reqVO.getCategory());
        wrapper.eqIfPresent(PayBillDO::getType, reqVO.getType());
        wrapper.betweenIfPresent(PayBillDO::getCreateTime, reqVO.buildCreateTime());
        List<Double> objs = selectObjs(wrapper, PayBillDO::getNumber);
        return objs.stream().reduce(0d, Double::sum);
    }

    default PageResult<PayBillDO> selectPage(Long userId, AppPayBillPageReqVO reqVO) {
        return selectPage(reqVO, new CoreLambdaQueryWrapper<PayBillDO>()
                .eqIfPresent(PayBillDO::getUserId, userId)
                .eqIfPresent(PayBillDO::getMode, reqVO.getMode())
                .eqIfPresent(PayBillDO::getCategory, reqVO.getCategory())
                .eqIfPresent(PayBillDO::getType, reqVO.getType())
                .betweenIfPresent(PayBillDO::getCreateTime, reqVO.buildCreateTime())
                .orderByDesc(PayBillDO::getId));
    }

}
